# -*- coding: utf-8 -*-
# Author   : ZhangQing
# Time     : 2025-08-04 23:27
# File     : chat_interface.py
# Project  : codebuddy_craft
# Desc     :
# frontend/components/chat_interface.py
import streamlit as st
import asyncio
from typing import Dict, Any, List, Optional
from datetime import datetime


class ChatInterface:
    """聊天界面组件"""
    
    def __init__(self, api_client, state_manager):
        self.api_client = api_client
        self.state_manager = state_manager
    
    def render(self, project_id: str, current_file: Optional[Dict[str, Any]] = None):
        """渲染聊天界面"""
        
        # 初始化聊天历史
        chat_key = f"chat_history_{project_id}"
        if chat_key not in st.session_state:
            st.session_state[chat_key] = []
        
        # 聊天消息显示容器
        chat_container = st.container()
        
        # 渲染聊天历史
        with chat_container:
            self._render_chat_history(st.session_state[chat_key])
        
        # 输入区域
        self._render_input_area(project_id, current_file, chat_key)
        
        # 快捷操作按钮
        self._render_quick_actions(project_id, current_file, chat_key)
    
    def _render_chat_history(self, chat_history: List[Dict[str, Any]]):
        """渲染聊天历史"""
        
        if not chat_history:
            st.info("💬 开始与 AI 助手对话吧！\n\n你可以：\n- 🔍 使用 @文件名 引用特定文件\n- 💡 描述需求生成代码\n- 🐛 寻求调试帮助")
            return
        
        for i, message in enumerate(chat_history):
            if message['role'] == 'user':
                with st.chat_message("user"):
                    st.write(message['content'])
                    if message.get('timestamp'):
                        st.caption(f"🕐 {message['timestamp']}")
            
            elif message['role'] == 'assistant':
                with st.chat_message("assistant"):
                    # 如果消息包含代码，特殊处理
                    if message.get('code_block'):
                        st.write(message['content'])
                        
                        # 显示代码块
                        language = message.get('language', 'python')
                        st.code(message['code_block'], language=language)
                        
                        # 代码操作按钮
                        col1, col2, col3 = st.columns(3)
                        
                        with col1:
                            if st.button("📋 复制", key=f"copy_code_{i}"):
                                st.session_state['clipboard'] = message['code_block']
                                st.success("代码已复制！")
                        
                        with col2:
                            if st.button("💾 保存为文件", key=f"save_as_file_{i}"):
                                self._show_save_dialog(message['code_block'], language)
                        
                        with col3:
                            if st.button("🔍 分析代码", key=f"analyze_code_{i}"):
                                self._analyze_generated_code(message['code_block'])
                    
                    else:
                        st.write(message['content'])
                    
                    if message.get('timestamp'):
                        st.caption(f"🤖 {message['timestamp']}")
            
            elif message['role'] == 'system':
                with st.chat_message("assistant"):
                    st.info(message['content'])
    
    def _render_input_area(self, project_id: str, current_file: Optional[Dict[str, Any]], chat_key: str):
        """渲染输入区域"""
        
        # 文件引用提示
        if current_file:
            st.caption(f"💡 当前文件: {current_file['name']} - 使用 @{current_file['name']} 引用")
        
        # 聊天输入
        user_input = st.chat_input("请描述您的需求或问题...")
        
        if user_input:
            # 添加用户消息到历史
            user_message = {
                'role': 'user',
                'content': user_input,
                'timestamp': datetime.now().strftime("%H:%M:%S")
            }
            st.session_state[chat_key].append(user_message)
            
            # 生成AI响应
            with st.spinner("🤖 AI 正在思考..."):
                response = asyncio.run(self._generate_ai_response(
                    user_input, project_id, current_file
                ))
            
            # 添加AI响应到历史
            if response:
                st.session_state[chat_key].append(response)
            
            # 刷新页面显示新消息
            st.experimental_rerun()
    
    def _render_quick_actions(self, project_id: str, current_file: Optional[Dict[str, Any]], chat_key: str):
        """渲染快捷操作按钮"""
        
        st.markdown("### 🚀 快捷操作")
        
        col1, col2 = st.columns(2)
        
        with col1:
            if st.button("💡 生成代码", key="quick_generate"):
                self._show_code_generation_dialog(project_id, chat_key)
            
            if st.button("🐛 调试代码", key="quick_debug"):
                if current_file:
                    self._start_debug_session(current_file, chat_key)
                else:
                    st.warning("请先选择一个文件")
        
        with col2:
            if st.button("📚 解释代码", key="quick_explain"):
                if current_file:
                    self._explain_current_file(current_file, chat_key)
                else:
                    st.warning("请先选择一个文件")
            
            if st.button("🔄 重构代码", key="quick_refactor"):
                if current_file:
                    self._suggest_refactoring(current_file, chat_key)
                else:
                    st.warning("请先选择一个文件")
        
        # 清空聊天历史
        if st.button("🗑️ 清空对话", key="clear_chat"):
            st.session_state[chat_key] = []
            st.experimental_rerun()
    
    async def _generate_ai_response(
        self, 
        user_input: str, 
        project_id: str, 
        current_file: Optional[Dict[str, Any]]
    ) -> Dict[str, Any]:
        """生成AI响应"""
        
        try:
            # 检查是否是代码生成请求
            if any(keyword in user_input.lower() for keyword in ['写', '生成', '创建', '实现', 'write', 'generate', 'create']):
                return await self._handle_code_generation(user_input)
            
            # 检查是否包含@文件引用
            elif '@' in user_input:
                return await self._handle_file_reference(user_input, project_id)
            
            # 一般性问答
            else:
                return await self._handle_general_chat(user_input)
        
        except Exception as e:
            return {
                'role': 'assistant',
                'content': f"抱歉，处理您的请求时出现错误：{str(e)}",
                'timestamp': datetime.now().strftime("%H:%M:%S")
            }
    
    async def _handle_code_generation(self, user_input: str) -> Dict[str, Any]:
        """处理代码生成请求"""
        
        try:
            # 检测编程语言
            language = self._detect_language_from_input(user_input)
            
            # 调用代码生成API
            result = await self.api_client.generate_code({
                'prompt': user_input,
                'language': language,
                'style': 'professional',
                'include_comments': True
            })
            
            if result['code'] == 200:
                data = result['data']
                return {
                    'role': 'assistant',
                    'content': data.get('explanation', '代码生成完成！'),
                    'code_block': data['code_block'],
                    'language': language,
                    'timestamp': datetime.now().strftime("%H:%M:%S")
                }
            else:
                return {
                    'role': 'assistant',
                    'content': '抱歉，代码生成失败。请重新描述您的需求。',
                    'timestamp': datetime.now().strftime("%H:%M:%S")
                }
        
        except Exception as e:
            return {
                'role': 'assistant',
                'content': f'代码生成出现错误：{str(e)}',
                'timestamp': datetime.now().strftime("%H:%M:%S")
            }
    
    async def _handle_file_reference(self, user_input: str, project_id: str) -> Dict[str, Any]:
        """处理文件引用请求"""
        
        try:
            # 提取@引用
            import re
            references = re.findall(r'@(\S+)', user_input)
            
            if references:
                scope = '/'.join(references)
                
                # 调用代码分析API
                result = await self.api_client.analyze_code({
                    'project_id': project_id,
                    'scope': f"@{scope}",
                    'prompt': user_input
                })
                
                if result['code'] == 200:
                    data = result['data']
                    
                    content = f"基于 @{scope} 的分析结果：\n\n"
                    content += data.get('summary', '')
                    
                    if data.get('issues'):
                        content += f"\n\n发现 {len(data['issues'])} 个问题："
                        for issue in data['issues'][:3]:  # 显示前3个问题
                            content += f"\n- 第{issue['line']}行: {issue['message']}"
                    
                    if data.get('solution'):
                        return {
                            'role': 'assistant',
                            'content': content,
                            'code_block': data['solution'],
                            'language': 'python',
                            'timestamp': datetime.now().strftime("%H:%M:%S")
                        }
                    else:
                        return {
                            'role': 'assistant',
                            'content': content,
                            'timestamp': datetime.now().strftime("%H:%M:%S")
                        }
                else:
                    return {
                        'role': 'assistant',
                        'content': '无法分析指定的文件，请检查文件是否存在。',
                        'timestamp': datetime.now().strftime("%H:%M:%S")
                    }
            else:
                return {
                    'role': 'assistant',
                    'content': '请使用 @文件名 的格式引用文件。',
                    'timestamp': datetime.now().strftime("%H:%M:%S")
                }
        
        except Exception as e:
            return {
                'role': 'assistant',
                'content': f'文件分析出现错误：{str(e)}',
                'timestamp': datetime.now().strftime("%H:%M:%S")
            }
    
    async def _handle_general_chat(self, user_input: str) -> Dict[str, Any]:
        """处理一般性聊天"""
        
        # 简单的问答逻辑，实际应该调用LLM API
        responses = {
            'hello': '你好！我是 CodeBuddy Craft，您的智能编程助手。有什么可以帮助您的吗？',
            'help': '我可以帮您：\n- 生成代码\n- 调试问题\n- 分析代码\n- 解释功能\n- 代码重构\n\n请告诉我您的具体需求！',
            'thanks': '不客气！很高兴能帮助您编程。如果还有其他问题，随时告诉我！'
        }
        
        user_lower = user_input.lower()
        
        if any(keyword in user_lower for keyword in ['hello', 'hi', '你好', '您好']):
            content = responses['hello']
        elif any(keyword in user_lower for keyword in ['help', '帮助', '怎么用']):
            content = responses['help']
        elif any(keyword in user_lower for keyword in ['thanks', 'thank', '谢谢', '感谢']):
            content = responses['thanks']
        else:
            content = '我理解您的问题。请告诉我更多细节，或者使用以下格式：\n- 生成代码：描述您需要的功能\n- 分析代码：使用 @文件名 引用特定文件\n- 调试问题：描述遇到的错误'
        
        return {
            'role': 'assistant',
            'content': content,
            'timestamp': datetime.now().strftime("%H:%M:%S")
        }
    
    def _detect_language_from_input(self, user_input: str) -> str:
        """从用户输入中检测编程语言"""
        
        language_keywords = {
            'python': ['python', 'py', 'django', 'flask', 'pandas'],
            'javascript': ['javascript', 'js', 'node', 'react', 'vue'],
            'java': ['java', 'spring', 'maven'],
            'cpp': ['c++', 'cpp', 'c plus plus'],
            'go': ['go', 'golang'],
            'rust': ['rust'],
            'typescript': ['typescript', 'ts']
        }
        
        user_lower = user_input.lower()
        
        for lang, keywords in language_keywords.items():
            if any(keyword in user_lower for keyword in keywords):
                return lang
        
        return 'python'  # 默认Python
    
    def _show_save_dialog(self, code: str, language: str):
        """显示保存对话框"""
        
        with st.expander("💾 保存为文件", expanded=True):
            filename = st.text_input(
                "文件名:",
                value=f"generated_code.{self._get_extension(language)}",
                key="save_filename"
            )
            
            if st.button("保存", key="confirm_save"):
                # 这里应该调用API保存文件
                st.success(f"代码已保存为 {filename}")
    
    def _get_extension(self, language: str) -> str:
        """根据语言获取文件扩展名"""
        
        extensions = {
            'python': 'py',
            'javascript': 'js',
            'typescript': 'ts',
            'java': 'java',
            'cpp': 'cpp',
            'go': 'go',
            'rust': 'rs'
        }
        
        return extensions.get(language, 'txt')
    
    def _analyze_generated_code(self, code: str):
        """分析生成的代码"""
        
        with st.expander("🔍 代码分析", expanded=True):
            st.info("正在分析代码...")
            
            # 简单的代码统计
            lines = len(code.split('\n'))
            chars = len(code)
            words = len(code.split())
            
            col1, col2, col3 = st.columns(3)
            
            with col1:
                st.metric("代码行数", lines)
            
            with col2:
                st.metric("字符数", chars)
            
            with col3:
                st.metric("单词数", words)
            
            # 检查基本问题
            issues = []
            if 'TODO' in code:
                issues.append("包含 TODO 标记")
            if len(code.split('\n')) > 50:
                issues.append("代码较长，建议拆分")
            if code.count('def ') > 5:
                issues.append("函数较多，考虑模块化")
            
            if issues:
                st.warning("发现以下建议：")
                for issue in issues:
                    st.write(f"- {issue}")
            else:
                st.success("代码看起来不错！")
    
    def _show_code_generation_dialog(self, project_id: str, chat_key: str):
        """显示代码生成对话框"""
        
        with st.expander("💡 代码生成助手", expanded=True):
            prompt = st.text_area(
                "请描述您需要的功能:",
                placeholder="例如：写一个Python函数，用于读取CSV文件并计算数据统计信息",
                key="generation_prompt"
            )
            
            col1, col2 = st.columns(2)
            
            with col1:
                language = st.selectbox(
                    "编程语言:",
                    ["Python", "JavaScript", "Java", "C++", "Go", "Rust"],
                    key="generation_language"
                )
            
            with col2:
                style = st.selectbox(
                    "代码风格:",
                    ["专业", "简洁", "详细注释", "初学者友好"],
                    key="generation_style"
                )
            
            if st.button("生成代码", key="confirm_generation"):
                if prompt:
                    # 添加到聊天历史
                    user_message = {
                        'role': 'user',
                        'content': f"使用{language}生成{style}风格的代码：{prompt}",
                        'timestamp': datetime.now().strftime("%H:%M:%S")
                    }
                    st.session_state[chat_key].append(user_message)
                    
                    # 生成响应
                    with st.spinner("生成中..."):
                        response = asyncio.run(self._handle_code_generation(prompt))
                        st.session_state[chat_key].append(response)
                    
                    st.success("代码生成完成！")
                    st.experimental_rerun()
                else:
                    st.warning("请输入功能描述")
    
    def _start_debug_session(self, current_file: Dict[str, Any], chat_key: str):
        """开始调试会话"""
        
        debug_message = {
            'role': 'system',
            'content': f"🐛 开始调试 {current_file['name']}...\n\n请描述遇到的问题或错误信息。",
            'timestamp': datetime.now().strftime("%H:%M:%S")
        }
        st.session_state[chat_key].append(debug_message)
        st.experimental_rerun()
    
    def _explain_current_file(self, current_file: Dict[str, Any], chat_key: str):
        """解释当前文件"""
        
        explain_message = {
            'role': 'system',
            'content': f"📚 正在分析 {current_file['name']} 的功能...\n\n请稍等，我来为您解释这个文件的作用。",
            'timestamp': datetime.now().strftime("%H:%M:%S")
        }
        st.session_state[chat_key].append(explain_message)
        st.experimental_rerun()
    
    def _suggest_refactoring(self, current_file: Dict[str, Any], chat_key: str):
        """建议重构"""
        
        refactor_message = {
            'role': 'system',
            'content': f"🔄 正在分析 {current_file['name']} 的重构机会...\n\n我会为您提供代码优化建议。",
            'timestamp': datetime.now().strftime("%H:%M:%S")
        }
        st.session_state[chat_key].append(refactor_message)
        st.experimental_rerun()
